package com.srcgen.builder;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSON;
import com.srcgen.config.ApiConfig;
import com.srcgen.config.ControllerConfig;
import com.srcgen.config.ConvertorConfig;
import com.srcgen.config.DAOConfig;
import com.srcgen.config.DTOConfig;
import com.srcgen.config.DaoImplConfig;
import com.srcgen.config.ModelConfig;
import com.srcgen.config.Mysql2JavaType;
import com.srcgen.config.ServiceImplConfig;
import com.srcgen.config.VoConfig;
import com.srcgen.domain.TableColumnsDO;
import com.srcgen.domain.entity.TableEntity;
import com.srcgen.utils.CamelCaseUtils;

/**
 * <一句话功能简述>
 * <功能详细描述>
 *
 * @auth:DONNIE
 * @see: [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class TemplateMapBuilder {

    public TemplateMapBuilder(){
    }

    public Map<String,ParentConfig> build(){
        return build(this);
    }
    public static Map<String,ParentConfig> build(TemplateMapBuilder builder){
        formatColumns(builder);

        Map<String,ParentConfig> map = new HashMap();
        String domain = CamelCaseUtils.toCapitalize(builder.tableName);

        if(builder.apiEnabled){
            ApiConfig apiConfig = new ApiConfig();
            apiConfig.setClassName(domain+API_SUFFIX);//CaseBaseInfoDao
            if(StringUtils.isNoneEmpty(builder.apiPackage)){
                apiConfig.setClassPackage(builder.apiPackage);
            }
            if(StringUtils.isNoneEmpty(builder.apiSaveDir)){
                apiConfig.setSaveDir(builder.apiSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.apiTemplate)){
                apiConfig.setTemplateDir(builder.apiTemplate);
            }
            map.put("api",apiConfig);
        }

        if(builder.dtoEnabled){
        	DTOConfig dtoConfig = new DTOConfig();

            if(StringUtils.isNoneEmpty(builder.dtoPackage)){
            	dtoConfig.setClassPackage(builder.dtoPackage);
            }
            if(StringUtils.isNoneEmpty(builder.dtoSaveDir)){
            	dtoConfig.setSaveDir(builder.dtoSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.dtoTemplate)){
            	dtoConfig.setTemplateDir(builder.dtoTemplate);
            }
            dtoConfig.setClassName(domain+DTO_SUFFIX);
            map.put("qo",dtoConfig);
        }
        if(builder.voEnabled){
            VoConfig voConfig = new VoConfig();

            if(StringUtils.isNoneEmpty(builder.voPackage)){
               voConfig.setClassPackage(builder.voPackage);
            }
            if(StringUtils.isNoneEmpty(builder.voSaveDir)){
               voConfig.setSaveDir(builder.voSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.voTemplate)){
               voConfig.setTemplateDir(builder.voTemplate);
            }
            voConfig.setQueryParams(builder.columnList);
            voConfig.setClassName(domain+VO_SUFFIX);
            map.put("vo",voConfig);
        }
        if(builder.daoEnabled){
        	DAOConfig daoConfig = new DAOConfig();

            if(StringUtils.isNoneEmpty(builder.daoPackage)){
                daoConfig.setClassPackage(builder.daoPackage);
            }
            if(StringUtils.isNoneEmpty(builder.daoSaveDir)){
                daoConfig.setSaveDir(builder.daoSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.daoTemplate)){
                daoConfig.setTemplateDir(builder.daoTemplate);
            }
            daoConfig.setClassName(domain+DAO_SUFFIX);
            map.put("dao",daoConfig);
        }
        if(builder.hibernateEnabled){
        	DaoImplConfig hibernateConfig = new DaoImplConfig();

            if(StringUtils.isNoneEmpty(builder.hibernatePackage)){
                hibernateConfig.setClassPackage(builder.hibernatePackage);
            }
            if(StringUtils.isNoneEmpty(builder.hibernateSaveDir)){
                hibernateConfig.setSaveDir(builder.hibernateSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.hibernateTemplate)){
                hibernateConfig.setTemplateDir(builder.hibernateTemplate);
            }
            hibernateConfig.setClassName(domain+DAOIMPL_SUFFIX);
            map.put("hibernate",hibernateConfig);
        }
  
        if(builder.modelEnabled){
            ModelConfig modelConfig = new ModelConfig();

            if(StringUtils.isNoneEmpty(builder.modelPackage)){
                modelConfig.setClassPackage(builder.modelPackage);
            }
            if(StringUtils.isNoneEmpty(builder.modelSaveDir)){
                modelConfig.setSaveDir(builder.modelSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.modelTemplate)){
                modelConfig.setTemplateDir(builder.modelTemplate);
            }
            modelConfig.setPrimaryKey(builder.primarykey);
            modelConfig.setColumnsList(builder.columnList);
            System.out.println(JSON.toJSONString(modelConfig.getColumnsList()));
            modelConfig.setClassName(domain+MODEL_SUFFIX);
            map.put("model",modelConfig);
        }
        if(builder.serviceImplEnabled){
            ServiceImplConfig serviceImplConfig = new ServiceImplConfig();

            if(StringUtils.isNoneEmpty(builder.serviceImplPackage)){
                serviceImplConfig.setClassPackage(builder.serviceImplPackage);
            }
            if(StringUtils.isNoneEmpty(builder.serviceImplSaveDir)){
                serviceImplConfig.setSaveDir(builder.serviceImplSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.serviceImplTemplate)){
                serviceImplConfig.setTemplateDir(builder.serviceImplTemplate);
            }
            serviceImplConfig.setPrimaryKey(builder.primarykey.getAttrName());
            serviceImplConfig.setClassName(domain+SERVICEIMPL_SUFFIX);
            map.put("service",serviceImplConfig);
        }
        
        if(builder.controllerEnabled){
            ControllerConfig controllerConfig = new ControllerConfig();

            if(StringUtils.isNoneEmpty(builder.controllerPackage)){
            	controllerConfig.setClassPackage(builder.controllerPackage);
            }
            if(StringUtils.isNoneEmpty(builder.controllerSaveDir)){
            	controllerConfig.setSaveDir(builder.controllerSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.controllerTemplate)){
            	controllerConfig.setTemplateDir(builder.controllerTemplate);
            }
            controllerConfig.setClassName(domain+CONTROLLER_SUFFIX);
            map.put("controller",controllerConfig);
        }
        
        if(builder.convertorEnabled){
        	ConvertorConfig convertorConfig = new ConvertorConfig();

            if(StringUtils.isNoneEmpty(builder.convertorPackage)){
            	convertorConfig.setClassPackage(builder.convertorPackage);
            }
            if(StringUtils.isNoneEmpty(builder.convertorSaveDir)){
            	convertorConfig.setSaveDir(builder.convertorSaveDir);
            }
            if(StringUtils.isNoneEmpty(builder.convertorTemplate)){
            	convertorConfig.setTemplateDir(builder.convertorTemplate);
            }
            convertorConfig.setClassName(domain+CONVERTOR_SUFFIX);
            map.put("convertor",convertorConfig);
        }
        

        //替换项目名和包名
        //String projectPrefix = builder.projectName.split("-")[1];
        for(String key:map.keySet()){
            ParentConfig config = map.get(key);
            config.setClassPackage(config.getClassPackage()
            									.replace("${packageName}", builder.sysPackageName)
            									.replace("${autoModel}", builder.sysAutoModel));
            config.setSaveDir(builder.projectRoot+"/"+builder.projectName+"/"+ config.getSaveDir()
            									.replace("${saveDir}", builder.sysSaveDir)
            									.replace("${autoModel}", builder.sysAutoModel)
            									.replace("${projectName}",builder.projectName));
            
            config.setDescribe(builder.tableInfo.getTable_comment());
            config.setMethodDomain(domain);
        }


        return map;
    }

    /**
     * 格式化表字段
     * @param builder
     */
    private static void formatColumns(TemplateMapBuilder builder) {
        List<TableColumnsDO> columnsDOList = builder.columnList;
        if(CollectionUtils.isEmpty(columnsDOList)){
            throw new RuntimeException("表字段为空！");
        }
        for(TableColumnsDO columnsDO:columnsDOList){
            columnsDO.setJavaTypeName(Mysql2JavaType.getJavaTypeFromMysql(columnsDO.getData_type()));
            columnsDO.setAttrName( CamelCaseUtils.toCamelCase(columnsDO.getColumn_name()));//字段是驼峰
            columnsDO.setDomainName(CamelCaseUtils.toCapitalize(columnsDO.getColumn_name()));//首字母大写
          //  columnsDO.setColumn_comment(StringEncoderUtils.gb2312ToUtf8(columnsDO.getColumn_comment()));
            if("PRI".equals(columnsDO.getColumn_key())){
                builder.primarykey = columnsDO;
            }
        }
    }

    private TableColumnsDO primarykey;

    private static final String API_SUFFIX="Service";
    private static final String DTO_SUFFIX="DTO";
    private static final String VO_SUFFIX="VO";
    private static final String DAO_SUFFIX="Dao";
    private static final String DAOIMPL_SUFFIX="DaoImpl";
    private static final String MODEL_SUFFIX="";
    private static final String SERVICEIMPL_SUFFIX="ServiceImpl";
    private static final String CONTROLLER_SUFFIX="Controller";
    private static final String CONVERTOR_SUFFIX="Convoter";


    /**
     * 项目目录路径
     */
    private String projectRoot;

    /**
     * 表名
     */
    private String tableName;

    /**
     * 项目名称
     */
    private String projectName;

    /**
     * 表
     */
    private TableEntity tableInfo;


    /**
     * 表字段明细
     */
    private List<TableColumnsDO> columnList;
    
    private String sysPackageName;
    
    private String sysSaveDir;
    
    private String sysAutoModel;
    
    
    private boolean convertorEnabled = true;
    private String convertorPackage;
    private String convertorSaveDir;
    private String convertorTemplate;
    
    private boolean controllerEnabled = true;
    private String controllerPackage;
    private String controllerSaveDir;
    private String controllerTemplate;

    private boolean apiEnabled = true;
    private String apiPackage;
    private String apiSaveDir;
    private String apiTemplate;

    private boolean dtoEnabled = true;
    private String dtoPackage;
    private String dtoSaveDir;
    private String dtoTemplate;

    private boolean voEnabled = true;
    private String voPackage;
    private String voSaveDir;
    private String voTemplate;

    private boolean daoEnabled = true;
    private String daoPackage;
    private String daoSaveDir;
    private String daoTemplate;

    private boolean hibernateEnabled = true;
    private String hibernatePackage;
    private String hibernateSaveDir;
    private String hibernateTemplate;


    private boolean modelEnabled = true;
    private String modelPackage;
    private String modelSaveDir;
    private String modelTemplate;

    private boolean serviceImplEnabled = true;
    private String serviceImplPackage;
    private String serviceImplSaveDir;
    private String serviceImplTemplate;
    
    

    public TemplateMapBuilder setConvertorEnabled(boolean convertorEnabled) {
		this.convertorEnabled = convertorEnabled;
		return this;
	}

	public TemplateMapBuilder setConvertorPackage(String convertorPackage) {
		this.convertorPackage = convertorPackage;
		return this;
	}

	public TemplateMapBuilder setConvertorSaveDir(String convertorSaveDir) {
		this.convertorSaveDir = convertorSaveDir;
		return this;
	}

	public TemplateMapBuilder setConvertorTemplate(String convertorTemplate) {
		this.convertorTemplate = convertorTemplate;
		return this;
	}

	public TemplateMapBuilder setControllerEnabled(boolean controllerEnabled) {
		this.controllerEnabled = controllerEnabled;
		return this;
	}

	public TemplateMapBuilder setControllerPackage(String controllerPackage) {
		this.controllerPackage = controllerPackage;
		return this;
	}

	public TemplateMapBuilder setControllerSaveDir(String controllerSaveDir) {
		this.controllerSaveDir = controllerSaveDir;
		return this;
	}

	public TemplateMapBuilder setControllerTemplate(String controllerTemplate) {
		this.controllerTemplate = controllerTemplate;
		return this;
	}

    public TemplateMapBuilder setTableInfo(TableEntity tableInfo) {
        this.tableInfo = tableInfo;
        return this;
    }

    public TemplateMapBuilder setColumnList(List<TableColumnsDO> columnList) {
        this.columnList = columnList;
        return this;
    }

    public TemplateMapBuilder setProjectRoot(String projectRoot) {
        this.projectRoot = projectRoot;
        return this;
    }

    public TemplateMapBuilder setTableName(String tableName) {
        this.tableName = tableName;
        return this;
    }

    public TemplateMapBuilder setProjectName(String projectName) {
        this.projectName = projectName;
        return this;
    }

    public TemplateMapBuilder setApiPackage(String apiPackage) {
        this.apiPackage = apiPackage;
        return this;
    }

    public TemplateMapBuilder setApiSaveDir(String apiSaveDir) {
        this.apiSaveDir = apiSaveDir;
        return this;
    }

    public TemplateMapBuilder setApiEnabled(boolean apiEnabled) {
        this.apiEnabled = apiEnabled;
        return this;
    }

    public TemplateMapBuilder setApiTemplate(String apiTemplate) {
        this.apiTemplate = apiTemplate;
        return this;
    }

 

    public TemplateMapBuilder setDtoEnabled(boolean dtoEnabled) {
		this.dtoEnabled = dtoEnabled;
		return this;
	}

	public TemplateMapBuilder setDtoPackage(String dtoPackage) {
		this.dtoPackage = dtoPackage;
		return this;
	}

	public TemplateMapBuilder setDtoSaveDir(String dtoSaveDir) {
		this.dtoSaveDir = dtoSaveDir;
		return this;
	}

	public TemplateMapBuilder setDtoTemplate(String dtoTemplate) {
		this.dtoTemplate = dtoTemplate;
		return this;
	}

	public TemplateMapBuilder setVoEnabled(boolean voEnabled) {
        this.voEnabled = voEnabled;
        return this;
    }

    public TemplateMapBuilder setVoPackage(String voPackage) {
        this.voPackage = voPackage;
        return this;
    }

    public TemplateMapBuilder setVoSaveDir(String voSaveDir) {
        this.voSaveDir = voSaveDir;
        return this;
    }

    public TemplateMapBuilder setVoTemplate(String voTemplate) {
        this.voTemplate = voTemplate;
        return this;
    }

    public TemplateMapBuilder setDaoEnabled(boolean daoEnabled) {
        this.daoEnabled = daoEnabled;
        return this;
    }

    public TemplateMapBuilder setDaoPackage(String daoPackage) {
        this.daoPackage = daoPackage;
        return this;
    }

    public TemplateMapBuilder setDaoSaveDir(String daoSaveDir) {
        this.daoSaveDir = daoSaveDir;
        return this;
    }

    public TemplateMapBuilder setDaoTemplate(String daoTemplate) {
        this.daoTemplate = daoTemplate;
        return this;
    }

    public TemplateMapBuilder setHibernateEnabled(boolean hibernateEnabled) {
        this.hibernateEnabled = hibernateEnabled;
        return this;
    }

    public TemplateMapBuilder setHibernatePackage(String hibernatePackage) {
        this.hibernatePackage = hibernatePackage;
        return this;
    }

    public TemplateMapBuilder setHibernateSaveDir(String hibernateSaveDir) {
        this.hibernateSaveDir = hibernateSaveDir;
        return this;
    }

    public TemplateMapBuilder setHibernateTemplate(String hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
        return this;
    }



    public TemplateMapBuilder setModelEnabled(boolean modelEnabled) {
        this.modelEnabled = modelEnabled;
        return this;
    }

    public TemplateMapBuilder setModelPackage(String modelPackage) {
        this.modelPackage = modelPackage;
        return this;
    }

    public TemplateMapBuilder setModelSaveDir(String modelSaveDir) {
        this.modelSaveDir = modelSaveDir;
        return this;
    }

    public TemplateMapBuilder setModelTemplate(String modelTemplate) {
        this.modelTemplate = modelTemplate;
        return this;
    }

    public TemplateMapBuilder setServiceImplEnabled(boolean serviceImplEnabled) {
        this.serviceImplEnabled = serviceImplEnabled;
        return this;
    }

    public TemplateMapBuilder setServiceImplPackage(String serviceImplPackage) {
        this.serviceImplPackage = serviceImplPackage;
        return this;
    }

    public TemplateMapBuilder setServiceImplSaveDir(String serviceImplSaveDir) {
        this.serviceImplSaveDir = serviceImplSaveDir;
        return this;
    }

    public TemplateMapBuilder setServiceImplTemplate(String serviceImplTemplate) {
        this.serviceImplTemplate = serviceImplTemplate;
        return this;
    }

	public TemplateMapBuilder setSysPackageName(String sysPackageName) {
		this.sysPackageName = sysPackageName;
		return this;
	}

	public TemplateMapBuilder setSysSaveDir(String sysSaveDir) {
		this.sysSaveDir = sysSaveDir;
		return this;
	}

	public TemplateMapBuilder setSysAutoModel(String sysAutoModel) {
		this.sysAutoModel = sysAutoModel;
		return this;
	}

    
    
}
